#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys

sys.path.append('..')
from common_utils import CBBCommonUtils


def get_plugin_info():
    plugin_info = {
        "name": "centos_authentication_007 Check_the_boot_password",
        "plugin_id": "centos_authentication_007",
        "plugin_type": "Authentication",
        "info": "Check the boot (grub, lilo) password.",
        "level": "C",
        "module": "Safety reinforcement",
        "author": "fanyi",
        "keyword": "Safety reinforcement",
        "configable": "false",
    }
    return plugin_info


logger = None
cur_user = None
cur_module = None
cur_task = None


def set_plugin_logger(setter, user, module, task, *args, **kwargs):
    global logger, cur_user, cur_module, cur_task
    logger = setter
    cur_user = user
    cur_module = module
    cur_task = task


# 扫描函数
def scan(ip, sys_user, sys_pwd, flag=0):
    des_list = []
    error_count = 0
    # 标记,0没有,1安装/版本1,2版本2
    grub_flag = 0
    lilo_flag = 0
    logger.debug_info(cur_user, cur_module, cur_task+'_Scan', '', "Scan Start.")
    # 获取配置
    cmd = "find /boot/ -maxdepth 3 -name grub -o -name grub2 2>/dev/null"
    result, output = CBBCommonUtils.cbb_run_cmd(ip, cmd, username=sys_user, passwd=sys_pwd)
    if not result:
        # 遍历配置项
        for i, value in enumerate(output):
            if "grub2" in value:
                grub_flag = 2
            elif "grub" in value and grub_flag != 2:
                grub_flag = 1
    else:
        error_des = "CMD process ERROR. Error info: {}".format(result[0].replace("\n", ""))
        des_list.append(error_des)
        logger.debug_error(cur_user, cur_module, cur_task+'_Scan', '', error_des)
        error_count += 1
        return des_list, error_count
    # 获取配置
    cmd = "find /etc/ -maxdepth 3 -name lilo.conf 2>/dev/null"
    result, output = CBBCommonUtils.cbb_run_cmd(ip, cmd, username=sys_user, passwd=sys_pwd)
    if not result and len(output) != 0:
        lilo_flag = 1
    elif not result and len(output) == 0:
        pass
    else:
        error_des = "CMD process ERROR. Error info: {}".format(result[0].replace("\n", ""))
        des_list.append(error_des)
        logger.debug_error(cur_user, cur_module, cur_task+'_Scan', '', error_des)
        error_count += 1
        return des_list, error_count
    if grub_flag == 1:
        cmd = "cat /boot/grub/menu.lst | grep password"
        result, output = CBBCommonUtils.cbb_run_cmd(ip, cmd, username=sys_user, passwd=sys_pwd)
        if not result:
            if len(output) == 1 and "password=" in output[0]:
                set_des = "The boot is Safe."
                des_list.append(set_des)
                logger.debug_info(cur_user, cur_module, cur_task+'_Scan', '', set_des)
            else:
                error_count += 1
                set_des = "The boot is DANGEROUS. Please check and add the password."
                des_list.append(set_des)
                logger.debug_warning(cur_user, cur_module, cur_task+'_Scan', '', set_des)
        else:
            error_des = "CMD process ERROR. Error info: {}".format(result[0].replace("\n", ""))
            des_list.append(error_des)
            logger.debug_error(cur_user, cur_module, cur_task+'_Scan', '', error_des)
            error_count += 1
            return des_list, error_count
    elif grub_flag == 2:
        cmd = "cat /etc/grub.d/00_header | awk 'END {print}'"
        result, output = CBBCommonUtils.cbb_run_cmd(ip, cmd, username=sys_user, passwd=sys_pwd)
        if not result:
            if "password" in output[0]:
                set_des = "The boot is Safe."
                des_list.append(set_des)
                logger.debug_info(cur_user, cur_module, cur_task+'_Scan', '', set_des)
            else:
                error_count += 1
                set_des = "The boot is DANGEROUS. Please check and add the password."
                des_list.append(set_des)
                logger.debug_warning(cur_user, cur_module, cur_task+'_Scan', '', set_des)
        else:
            error_des = "CMD process ERROR. Error info: {}".format(result[0].replace("\n", ""))
            des_list.append(error_des)
            logger.debug_error(cur_user, cur_module, cur_task+'_Scan', '', error_des)
            error_count += 1
            return des_list, error_count
    if lilo_flag == 1:
        cmd = "cat /etc/lilo.conf | grep password"
        result, output = CBBCommonUtils.cbb_run_cmd(ip, cmd, username=sys_user, passwd=sys_pwd)
        if not result:
            if len(output) != 0 and "password=" in output[0]:
                set_des = "The boot is Safe."
                des_list.append(set_des)
                logger.debug_info(cur_user, cur_module, cur_task+'_Scan', '', set_des)
            else:
                error_count += 1
                set_des = "The boot is DANGEROUS. Please check and add the password."
                des_list.append(set_des)
                logger.debug_warning(cur_user, cur_module, cur_task+'_Scan', '', set_des)
        else:
            error_des = "CMD process ERROR. Error info: {}".format(result[0].replace("\n", ""))
            des_list.append(error_des)
            logger.debug_error(cur_user, cur_module, cur_task+'_Scan', '', error_des)
            error_count += 1
            return des_list, error_count
    des_list.append("Scan Complete.")
    logger.debug_info(cur_user, cur_module, cur_task+'_Scan', '', "Scan Complete.")
    # 是否加固
    if flag == 1:
        reinforce_des, reinforce_err = reinforce(ip, sys_user, sys_pwd)
        des_list.extend(reinforce_des)
    return des_list, error_count


# 加固函数
def reinforce(ip, sys_user, sys_pwd):
    des_list = []
    error_count = 0
    des = "This function can't be reinforcerd automatically.Please check and edit the password by yourself."
    des_list.append(des)
    logger.debug_info(cur_user, cur_module, cur_task+'_Reinforce', '', des)
    return des_list, error_count


# 回滚函数
def rollback(ip, sys_user, sys_pwd):
    des_list = []
    error_count = 0
    des = "This function don't need to rollback."
    des_list.append(des)
    logger.debug_info(cur_user, cur_module, cur_task+'_Reinforce', '', des)
    return des_list, error_count


def check(ip, *args, **kwargs):
    sys_user = kwargs.get("system_user")
    sys_pwd = kwargs.get("system_pwd")
    comm = kwargs.get("command")
    try:
        des_list = []
        logger.debug_info(cur_user, cur_module, cur_task+'_Check', '', "centos_authentication_007 Start")
        if comm == 1:
            des_scan, error_scan = scan(ip, sys_user, sys_pwd, flag=0)
            des_list.extend(des_scan)
            step_error = int(error_scan)
        elif comm == 2:
            des_reinforce, error_reinforce = scan(ip, sys_user, sys_pwd, flag=1)
            des_list.extend(des_reinforce)
            step_error = int(error_reinforce)
        elif comm == 3:
            des_rollback, error_rollback = rollback(ip, sys_user, sys_pwd)
            des_list.extend(des_rollback)
            step_error = int(error_rollback)
        else:
            return {"code": 3, "count": 0, "des": ['command must be 1/2/3']}
        logger.debug_info(cur_user, cur_module, cur_task+'_Check', '', "centos_authentication_007 Complete")
        if step_error == 0:
            code = 0
        elif step_error <= -1:
            code = 2
        else:
            code = 1
        return {"code": code, "count": step_error, "des": des_list}
    except Exception as er:
        code = 1
        des = ["ERROR:", str(er)]
        logger.debug_error(cur_user, cur_module, cur_task+'_Check', '', des)
        return {"code": code, "count": 0, "des": des}


#check(ip="100.2.91.150", system_user="root", system_pwd="admin", command=0, flag=0)
